package com.pc.cloud.utils;

import com.pc.cloud.services.DocumentBuilder;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.document.NumericField;
import org.json.JSONArray;
import org.json.JSONObject;

/**
 * Created by IntelliJ IDEA.
 * User: huangqinghe
 * Date: 13-4-25
 * Time: 14 08
 * To change this template use File | Settings | File Templates.
 */
public class DocumentUtils {
    
    public static String toJSON(DocumentBuilder builder) throws Exception {
		JSONObject pd = new JSONObject();
		pd.put("searchType", builder.getSearchType());
		JSONArray ks = new JSONArray();
		for(String k : builder.getKeys()) {
			ks.put(k);
		}
		pd.put("keys", ks);

		JSONArray ds = new JSONArray();
		for(Document d : builder.getDocs()) {
			ds.put(docToJSON(d));
		}
		pd.put("docs", ds);

		return pd.toString();
	}
    private static JSONObject docToJSON(Document doc) throws Exception {
		JSONObject dj = new JSONObject();
		dj.put("boost", doc.getBoost());
		JSONArray fields = new JSONArray();
		for(Fieldable f : doc.getFields()) {
			JSONObject fj = new JSONObject();
			fj.put("name", f.name());
			fj.put("value", f.stringValue());
			if(f instanceof Field) {
				fj.put("fieldType", "field");
				Field field = (Field)f;
				fj.put("isIndexed", field.isIndexed());
				fj.put("isStored", field.isStored());
				fj.put("isTokenized", field.isTokenized());
				fj.put("omitNorms", field.getOmitNorms());
				fj.put("boost", field.getBoost());
			} else if(f instanceof NumericField) {
				fj.put("fieldType", "numericField");
				NumericField nf = (NumericField)f;
				Number value = nf.getNumericValue();
				fj.put("valueType", value.getClass().getSimpleName());
			} else {
				throw new Exception(f.toString() + " has not supported yet!");
			}
			fields.put(fj);
		}
		dj.put("fields", fields);
		return dj;
	}

    public static Document jsonToDoc(JSONObject object) throws Exception {
		Document d = new Document();
		d.setBoost(object.getInt("boost"));
		JSONArray fields = object.getJSONArray("fields");
		for(int i=0;i<fields.length();i++) {
			JSONObject jf = fields.getJSONObject(i);
			String fieldType = jf.getString("fieldType");
			String name = jf.getString("name");
			Fieldable field = null;
			if("field".equals(fieldType)) {
				String value = jf .getString("value");
				boolean isIndexed = jf.getBoolean("isIndexed");
				boolean isStored = jf.getBoolean("isStored");
				boolean isTokenized = jf.getBoolean("isTokenized");
				boolean omitNorms = jf.getBoolean("omitNorms");
				int boost = jf.getInt("boost");

				Field.Store store;
				if(isStored) {
					store = Field.Store.YES;
				} else {
					store = Field.Store.NO;
				}

				Field.Index index = null;
				if(!isIndexed && !isTokenized && omitNorms) {
					index = Field.Index.NO;
				} else if(isIndexed && isTokenized && !omitNorms) {
					index = Field.Index.ANALYZED;
				} else if(isIndexed && !isTokenized && !omitNorms) {
					index = Field.Index.NOT_ANALYZED;
				} else if(isIndexed && !isTokenized && omitNorms) {
					index = Field.Index.NOT_ANALYZED_NO_NORMS;
				} else if(isIndexed && isTokenized && omitNorms) {
					index = Field.Index.ANALYZED_NO_NORMS;
				}

				field = new Field(name,value,store,index);
				field.setBoost(boost);
			} else if("numericField".equals(fieldType)) {
				String valueType = jf.getString("valueType");
				field = new NumericField(name);
				NumericField nf = (NumericField)field;
				if("Long".equals(valueType)) {
					nf.setLongValue(jf.getLong("value"));
				} else if("Integer".equals(valueType)) {
					nf.setIntValue(jf.getInt("value"));
				} else if("Double".equals(valueType)) {
					nf.setDoubleValue(jf.getDouble("double"));
				} else if("Float".equals(valueType)) {
					nf.setFloatValue(Float.valueOf(jf.getString("value")));
				}
			}

			d.add(field);
		}
		return d;
	}
}
